home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pine / ccmd / dir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-19  |  4.6 KB  |  245 lines

  1. /*
  2.  * Taken from net.sources.   Thanks to some unknown author somewhere
  3.  * out there.
  4.  */
  5.  
  6. /*
  7.  *    dir.c - contains routines which behave (hopefully) like the
  8.  *        similar versions on 4.2 BSD.
  9.  *
  10.  */
  11.  
  12. #ifdef MSDOS                /* entire file */
  13. #include <errno.h>
  14. #include <dir.h>
  15.  
  16. extern int errno;
  17. extern char *calloc();
  18.  
  19. /*
  20.  *    opendir - opens given directory and reads its contents into memory.
  21.  *    Other functions use this data or the DIR structure to do their work.
  22.  */
  23. DIR *
  24. opendir(dirname)
  25. char *dirname;
  26. {
  27.     struct direct **namelist;
  28.     DIR *dirptr;
  29.  
  30.     dirptr = (DIR *)calloc(1, sizeof(DIR));
  31.     if(dirptr == (DIR *)0)
  32.     {
  33.         errno = ENOMEM;
  34.         return((DIR *)0);
  35.     }
  36.     dirptr->d_magic = DMAGIC;
  37.     dirptr->d_pos = 0;
  38.     dirptr->d_length = scandir(dirname, &(dirptr->namelist),
  39.         (int (*)())0, (int (*)())0); 
  40.     if(dirptr->d_length < 0)
  41.     {
  42.         free((char *)dirptr);
  43.         return((DIR *)0);
  44.     }
  45.     return(dirptr);
  46. }
  47.  
  48. /*
  49.  *    readdir - returns the next directory structure from the list and
  50.  *    updates values in the DIR structure.
  51.  */
  52. struct direct *
  53. readdir(dirptr)
  54. DIR *dirptr;
  55. {
  56.     if(dirptr->d_magic != DMAGIC)
  57.     {
  58.         errno = ENOTDIR;
  59.         return((struct direct *)0);
  60.     }
  61.     if(dirptr->d_pos >= dirptr->d_length)
  62.     {
  63.         errno = ENFILE;
  64.         return((struct direct *)0);
  65.     }
  66.     return(dirptr->namelist[dirptr->d_pos++]);
  67. }
  68.  
  69. /*
  70.  *    telldir - return the current position of the directory.
  71.  */
  72. long
  73. telldir(dirptr)
  74. DIR *dirptr;
  75. {
  76.     if(dirptr->d_magic != DMAGIC)
  77.     {
  78.         errno = ENOTDIR;
  79.         return(-1L);
  80.     }
  81.     return((long)dirptr->d_pos);
  82. }
  83.  
  84. /*
  85.  *    seekdir - position the given DIR stream to position given.
  86.  */
  87. seekdir(dirptr, loc)
  88. DIR *dirptr;
  89. long loc;
  90. {
  91.     if(dirptr->d_magic != DMAGIC)
  92.     {
  93.         errno = ENOTDIR;
  94.         return(-1);
  95.     }
  96.     if(loc > (long)dirptr->d_length)
  97.     {
  98.         errno = EINVAL;
  99.         return(-1);
  100.     }
  101.     dirptr->d_pos = (int)loc;
  102.     return(0);
  103. }
  104.  
  105. /*
  106.  *    rewinddir - rewind given DIR to beginning
  107.  */
  108. rewinddir(dirptr)
  109. DIR *dirptr;
  110. {
  111.     if(dirptr->d_magic != DMAGIC)
  112.     {
  113.         errno = ENOTDIR;
  114.         return(-1);
  115.     }
  116.     dirptr->d_pos = 0;
  117.     return(0);
  118. }
  119.  
  120. /*
  121.  *    closedir - close given directory. destroy given DIR struct so we
  122.  *    know it is closed.
  123.  */
  124. closedir(dirptr)
  125. DIR *dirptr;
  126. {
  127.     if(dirptr->d_magic != DMAGIC)
  128.     {
  129.         errno = ENOTDIR;
  130.         return(-1);
  131.     }
  132.     dirptr->d_magic = ~DMAGIC;    /* mess it up a little */
  133.     freedir(dirptr->namelist);
  134.     free(dirptr);
  135.     return(0);
  136. }
  137.  
  138.  
  139.  
  140.  
  141. /****************************/
  142.  
  143. #include <dos.h>
  144.  
  145. #define NULL (char *)0
  146.  
  147. static struct direct buffer;
  148.  
  149. extern char *malloc(), *realloc();
  150.  
  151. scandir(dirname, namelist, select, compar)
  152. char *dirname;
  153. struct direct *(*namelist[]);
  154. int (*select)();
  155. int (*compar)();
  156. {
  157.     register struct direct **names;
  158.     register int dirno;
  159.     union REGS sregs, oregs;
  160.     struct SREGS segregs;
  161.     char *ptr, *paths;
  162.  
  163.     names = (struct direct **)calloc(1, sizeof(struct direct *));
  164.     paths = calloc(128, 1);
  165.     if(names == (struct direct **)0 || paths == NULL)
  166.     {
  167.         errno = ENOMEM;
  168.         return(-1);
  169.     }
  170.     strcpy(paths, dirname);
  171.     ptr = &paths[strlen(paths) - 1];
  172.     if(*ptr == '/' || *ptr == '\\')
  173.         *ptr = '\0';
  174.     strcat(paths, "/*.*");
  175.  
  176.     segread(&segregs);        /* set up segment registers */
  177.     ptr = (char *)&buffer;
  178.     sregs.h.ah = 0x1a;        /* set DTA to buffer */
  179.     sregs.x.dx = FP_OFF(ptr);    /* offset */
  180. #ifdef    M_I86LM
  181.     segregs.ds = FP_SEG(ptr);    /* pointer in large model */
  182. #endif /* M_I86LM */
  183.     intdosx(&sregs, &oregs, &segregs);
  184.     sregs.x.ax = 0x4e00;        /* search for first */
  185.     sregs.x.cx = 0x1f;        /* include all attributes */
  186.     sregs.x.dx = FP_OFF(paths);    /* offset to path */
  187. #ifdef    M_I86LM
  188.     segregs.ds = FP_SEG(paths);    /* segment for large model */
  189. #endif /* M_I86LM */
  190.     intdosx(&sregs, &oregs, &segregs);
  191.     if(oregs.x.cflag)
  192.     {
  193.         errno = ENOTDIR;
  194.         return(-1);
  195.     }
  196.     sregs.x.ax = 0x4f00;        /* search for next */
  197.     for(dirno = 0; oregs.x.cflag == 0; intdosx(&sregs, &oregs, &segregs))
  198.     {
  199.         if (!(buffer.d_attr & 0x08)) { /* skip Volume label */
  200.         for(ptr = buffer.d_name; *ptr; ptr++)
  201.             *ptr = tolower(*ptr);
  202.         if(select == (int (*)())0 || (*select)(&buffer))
  203.         {
  204.             names = (struct direct **)realloc((char *)names,
  205.                 (dirno + 2)*sizeof(struct direct *));
  206.             if(names == (struct direct **)0)
  207.             {
  208.                 errno = ENOMEM;
  209.                 return(-1);
  210.             }
  211.             names[dirno] = (struct direct *)calloc(1,
  212.                 sizeof(struct direct));
  213.             if(names[dirno] == (struct direct *)0)
  214.             {
  215.                 errno = ENOMEM;
  216.                 return(-1);
  217.             }
  218.             *names[dirno] = buffer;
  219.             names[++dirno] = (struct direct *)0;
  220.         }
  221.         }
  222.     }
  223.  
  224.     if(compar != (int (*)())0)
  225.         qsort((char *)names, dirno, sizeof(char *), compar);
  226.  
  227.     *namelist = names;
  228.     free(paths);            /* free temp space */
  229.     return(dirno);
  230. }
  231.  
  232. freedir(dirs)
  233. register struct direct **dirs;
  234. {
  235.     register int ii;
  236.  
  237.     if(dirs == (struct direct **)0)
  238.         return(-1);
  239.     for(ii = 0; dirs[ii] != (struct direct *)0; ii++)
  240.         free(dirs[ii]);
  241.     free(dirs);
  242.     return(0);
  243. }
  244. #endif /* MSDOS */
  245.